package model;

//主要是实现三个功能
//1.插入用户.用户注册的时候使用
//2.按名字查找用户,登陆的时候使用
//3.按照用户 id 查找 ,展示信息时使用

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class UserDao {
    //添加用户信息,用于注册用户
    public void add(User user) throws OrderSystemExecption {
        // 注意:这就是 jdbc 编程的基本流程了!!!
        //1.首先获取和数据库的连接(Datasource)  首先建立一个 datasource 类, 通过 datasource 类和数据库建立连接,
        //如何建立连接呢?通过 datasource 类然后再创建一个MysqlDatasource实例对象,
        // 依据实例对象通过 set url password username 方法设置相关数据库的属性,然后调用通过实例对象调用 getconnection
        //方法,这样就可以和数据库建立连接, 如果建立失败,就会抛出一个 sqlexecption 异常信息,这样异常信息就会提示连接过程中的异常信息.

        Connection connection=DBUtil.getConnection();

        //2.拼装 sql 语句(PrepareStatement)
        //首先创建模板 sql 语句,然后创建一个 PrepareStatement 实例对象,在创建实例对象的时候传入一个由字符串组成的 sql 语句模板,
        // 如果里面有一些动态变化的变量的时候我们采用 ? 进行占位处理,对象创建完成之后,再通过 statement
        // 实例对象用 setInt setDouble setString 方法把通配符进行替换成我们需要传入的变量

        String sql = "insert into user values(null,?,?,?)";
        PreparedStatement statement = null;
        try {
            statement = connection.prepareStatement(sql);
            statement.setString(1,user.getName());
            statement.setString(2,user.getPassword());
            statement.setInt(3,user.getIsadmin());
            //3.执行 sql 语句(executeQuery executeUpdate)
            //执行方法直接进行 executeQuery executeUpdate 两个方法进行操作 ,添加/删除/修改 直接调用 executeUpdate 进行操作,
            // 其返回值为受影响的行数,返回值为 int 类型,  查询操作采用 executeQuery 方法,返回值为 resultSet 通过遍历resultSet结果集,
            // 返回查询的结果.
            int ret = statement.executeUpdate();
            if(ret!=1){
                throw new OrderSystemExecption("插入用户失败");
            }
            System.out.println("插入用户成功");
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            //4.关闭连接(close)(如果时查询语句还需要进行遍历结果集合) 首先关闭 resultset 然后是 statement 最后关闭 connection
            // 如果是通过DriverManager类的getConnection()方法得到的Connection实例，
            // 在调用close()方法关闭Connection实例的同时也会关闭Statement实例和ResultSet实例。
            // 但是通常情况下需要采用数据库连接池，在调用连接池得到的Connection实例的close()方法时，
            // Connection实例可能没有被释放，而是放回了连接池中，又被其他连接调用，这种情况下如果不手动关闭Statement实例和ResultSet实例，
            // 他们在Connection中可能会越来越多，虽然JVM的垃圾回收机制会定时清理缓存，但是如果清理不及时，当数据库连接达到一定数量时，
            // 将严重影响数据库和计算机的运行速度，甚至导致软件或系统瘫痪
            DBUtil.close(connection,statement,null);
        }
    }
    //根据用户名查找用户信息,用于登录用户
    public User selectByName(String name) throws OrderSystemExecption {

        //1.建立连接
        Connection connection = DBUtil.getConnection();

        //2.拼装 sql 语句
        String sql = "select * from user where name = ?";
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        try {
            statement = connection.prepareStatement(sql);
            statement.setString(1,name);
            //执行语句操作
             resultSet = statement.executeQuery();
            if(resultSet.next()){
                User user = new User();
                user.setUserid(resultSet.getInt("userid"));
                user.setName(resultSet.getString("name"));
                user.setPassword(resultSet.getString("password"));
                user.setIsadmin(resultSet.getInt("isadmin"));
                return user;
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            throw new OrderSystemExecption("按姓名查找用户失败");
        }finally {
            DBUtil.close(connection,statement,resultSet);
        }
        return null;
    }
    //根据用户 id 进行查找用户,根据点餐表的用户id,查询用户信息
    public User selectByUserId(Integer userid) throws OrderSystemExecption {
        //1.建立连接
        Connection connection=DBUtil.getConnection();
        //2.构造 sql 语句
        String sql = "select * from user where userid = ?";
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        try {
             statement = connection.prepareStatement(sql);
             statement.setInt(1,userid);
             //3.执行 sql
             resultSet = statement.executeQuery();
             //4. 遍历结果集, userid 是主键,不会重复的,最多只能查询到一条语句
             if(resultSet.next()){
                 User user = new User();
                 user.setUserid(resultSet.getInt("userid"));
                 user.setName(resultSet.getString("name"));
                 user.setPassword(resultSet.getString("password"));
                 user.setIsadmin(resultSet.getInt("isadmin"));
                 return user;
             }

        } catch (SQLException throwables) {
            throwables.printStackTrace();
            throw new OrderSystemExecption("根据用户 id 查找用户信息失败");
        }finally {
            DBUtil.close(connection,statement,resultSet);
        }
        return null;
    }
//在这里进行 UserDao 的单元测试
    public static void main(String[] args) throws OrderSystemExecption {
        //这个方法中进行 UserDao 的单元测试
        UserDao userDao = new UserDao();
        // 测试 插入方法
//        User user = new User();
//        user.setName("马龙");
//        user.setPassword("123123");
//        user.setIsadmin(0);
//        userDao.add(user);
        User user = userDao.selectByName("马龙");
        System.out.println("按名字查找");
        System.out.println(user);

        User user1 = userDao.selectByUserId(1);
        System.out.println("按 id 查找");
        System.out.println(user1);

    }

}
